package com.shixu.framework.plugins.weixin.service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import net.sf.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.shixu.framework.core.AppContext;
import com.shixu.framework.plugins.weixin.pojo.AccessToken;
import com.shixu.framework.plugins.weixin.util.HttpKit;
/**
 * 微信Oauth和支付工具类
 *
 */
public class Oauth {
	private static Logger log = LoggerFactory.getLogger(Oauth.class);  
	
    private static final String CODE_URI = "http://open.weixin.qq.com/connect/oauth2/authorize";
    private static final String TOKEN_URI = "https://api.weixin.qq.com/sns/oauth2/access_token";
    private static final String REFRESH_TOKEN_URI = "https://api.weixin.qq.com/sns/oauth2/refresh_token";

    private String appid;
    private String secret;

	public Oauth() {
        super();
        this.appid = AppContext.getInstance().getString("appid");
        this.secret = AppContext.getInstance().getString("appsecret");
    }

    public Oauth(String appid, String secret) {
        super();
        this.appid = appid;
        this.secret = secret;
    }

    /**
     * 请求code
     * @return
     * @throws UnsupportedEncodingException 
     */
    public String getCode() throws UnsupportedEncodingException {
        
        return getCode(AppContext.getInstance().getString("redirect_uri"));
    }

    /**
     * 请求code
     * @return
     * @throws UnsupportedEncodingException 
     */
    public String getCode(String url) throws UnsupportedEncodingException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("appid", getAppid());
        params.put("response_type", "code");
        params.put("redirect_uri", url);
        params.put("scope", "snsapi_base"); // snsapi_base（不弹出授权页面，只能拿到用户openid）snsapi_userinfo
        // （弹出授权页面，这个可以通过 openid 拿到昵称、性别、所在地）
        params.put("state", "wx#wechat_redirect");
        String para = Pay.createSign(params, true);
        return CODE_URI + "?" + para;
    }
    
    /**
     * 通过code 换取 access_token
     * @param code
     * @return
     * @throws IOException 
     * @throws NoSuchProviderException 
     * @throws NoSuchAlgorithmException 
     * @throws KeyManagementException 
     */
    public String getToken(String code) throws Exception {
    	
        Map<String, String> params = new HashMap<String, String>();
        
        params.put("appid", getAppid());
        params.put("secret", getSecret());
        params.put("code", code);
        params.put("grant_type", "authorization_code");
        
        String tokenStr = HttpKit.get(TOKEN_URI, params);
		
        return tokenStr;
//		return this.pasreToken(tokenStr);
    }
    
    public String getOauthToken(String code) throws Exception{
    	String tokenStr = null;
		
    	tokenStr = getToken(code);
		
		log.info("获取access_token成功，有效时长{}秒 token:{}", tokenStr);
    	
    	return tokenStr;
    }
    
    private AccessToken pasreToken(String tokenStr){
    	AccessToken token = new AccessToken();
 		JSONObject map = JSONObject.fromObject(tokenStr);

 		if (map.has("errcode")) {
 			log.error("获取access token失败：" + tokenStr);
 			return token;
 		}
 		
 		token.setToken(map.getString("access_token"));
 		token.setExpiresIn(map.getInt("expires_in"));
 		token.setUpdateTime(new Date().getTime());
 		token.setRefreshToken(map.getString("refresh_token"));
 		return token;
    }

    /**
     * 刷新 access_token
     * @param refreshToken
     * @return
     * @throws IOException 
     * @throws NoSuchProviderException 
     * @throws NoSuchAlgorithmException 
     * @throws KeyManagementException 
     */
    public String getRefreshToken(String refreshToken) throws Exception {
        Map<String, String> params = new HashMap<String, String>();
        params.put("appid", getAppid());
        params.put("grant_type", "refresh_token");
        params.put("refresh_token", refreshToken);
        
        String tokenStr = HttpKit.get(REFRESH_TOKEN_URI, params);
		
		return tokenStr;
    }

    public String getAppid() {
        return appid;
    }

    public void setAppid(String appid) {
        this.appid = appid;
    }

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }
}
